<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>
<body>
    <div id="app">
        <p>{{count}}</p>
        <p><button @click="count++">count++</button></p>
        <p><button @click="count=10">count赋值</button></p>
        <p><button @click="addCount">count++</button></p>
        <hr>
        <p>
            {{obj.a}}
        </p>
        <p>
            <button @click="obj.a++">obj.a++</button>
            <button @click="obj={a:0,b:0}">重置obj</button>
        </p>
    </div>
</body>
<script>
    // console.log(Vue);  

    // 组合式

    // Vue3中   全局对象(存放各种方法 -> 后期要用)
    let {createApp} = Vue;   
    let {ref,reactive,readonly} = Vue;
    let {watch} = Vue;

    var app = createApp({
       // 采用组合式写法

       setup:function(props){
            // 1. 可以在setup函数中定义数据 方法 计算属性 生命周期钩子函数  
            // 2. 定义 数据 方法 计算属性 通过return值返回   =>  返回的数据和方法,就是代理对象接收的
            // 3. props有一个形参 可以接收父组件传入的数据 (作为子组件时 )

            // 如何定义数据?
            // ref()
            // reactive()
            // readonly()

            // 此写法 可以定义死数据 -> 无法监听到数据改变,同步到视图 
            // let count = 10;  // 10
            // function addCount() {
            //     count++;
            //     console.log(count);
            // }

            // ref()  =>     常用于定义值类型的数据(引入类型也可以)
            // ref() 让我们能创造一种对任意值的 “引用”，并能够在不丢失响应性的前提下传递这些引用。
            // 方法返回一个ref对象, 对象中存在value属性(有取值拦截和赋值拦截),存储传入数据,监听到value属性值发生改变,更新视图
            // ref对象 在template和选项式中使用时默认会被解包 ->  a. 取值时 => 自动获取ref对象的value值存储到proxy对象/  也可以在模板中直接使用  b. 赋值时将对应的数据存储到ref对象中

            // reactive() => 常用于定义引用类型的数据

            let count = ref(10);
            console.log(count);
            let addCount = ()=>{
                count.value = 10; 
            }

            // ref 定义对象数据也可以  => ref对数据的监听是深度监听(如果对象上的属性发生变化 也会触发视图更新 -> 默认不会被watch捕获到)
            let obj = ref({a:1,b:2});  // ref对象 => {value:{a:1,b:2}}
            // obj.value = {a:10,b:20}

            console.log(obj);


            // 数据监听的写法  (watch对数据的监听是浅层的)
            // watch 监听对象数据时 默认是浅层的 
            // 监听ref对象是 只监听ref对象.value发生改变   (深度监听需要设置 {deep:true})


            watch(count,function(newVal,oldVal){
                console.log("count发生改变",newVal,oldVal);
            })

            // watch 监听对象数据时 默认是浅层的 obj.value发生改变
            watch(obj,function(newVal,oldVal){
                console.log("obj发生改变",newVal,oldVal);
            })
            
            // watch 监听对象数据时 深度监听 
            // watch(obj,function(newVal,oldVal){
            //     console.log("obj深度监听改变",newVal,oldVal);
            // },{deep:true})




            // 原理 => 闭包
            return {
                count:count,  // count:ref对象
                obj,
                addCount:addCount,
            }

       },

        // 依旧可以使用选项式写法
        mounted() {
            console.log("this->代理对象",this);
            console.log(this.count);
            this.count = 100;
        },
    })

    app.mount("#app");








</script>
</html>